Backported Google Talk mail notification support and disabling of the mail notificati...
[adiumx.git] / Frameworks / Adium Framework / CSNewContactAlertWindowController.m
blobf56ee929f0632ad2db26c1fbb947ffa256f88e92
1 /* 
2  * Adium is the legal property of its developers, whose names are listed in the copyright file included
3  * with this source distribution.
4  * 
5  * This program is free software; you can redistribute it and/or modify it under the terms of the GNU
6  * General Public License as published by the Free Software Foundation; either version 2 of the License,
7  * or (at your option) any later version.
8  * 
9  * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
10  * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
11  * Public License for more details.
12  * 
13  * You should have received a copy of the GNU General Public License along with this program; if not,
14  * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
15  */
17 #import "AIActionDetailsPane.h"
18 #import "AIImageTextCellView.h"
19 #import "AIListObject.h"
20 #import "CSNewContactAlertWindowController.h"
21 #import "ESContactAlertsController.h"
22 #import "ESContactAlertsViewController.h"
24 #define NEW_ALERT_NIB                   @"NewAlert"
25 #define NEW_ALERT_NO_EVENTS_NIB @"NewAlertNoEvents"
27 @interface CSNewContactAlertWindowController (PRIVATE)
28 - (id)initWithWindowNibName:(NSString *)windowNibName 
29                                           alert:(NSDictionary *)inAlert
30                           forListObject:(AIListObject *)inListObject
31                         notifyingTarget:(id)inTarget
32                                    delegate:(id)inDelegate 
33                                    oldAlert:(id)inOldAlert
34                  configureForGlobal:(BOOL)inConfigureForGlobal
35                          defaultEventID:(NSString *)inDefaultEventID;
36 - (void)configureForEvent;
37 - (void)saveDetailsPaneChanges;
38 - (void)configureDetailsPane;
39 - (void)cleanUpDetailsPane;
41 - (void)updateHeaderView;
42 @end
44 @implementation CSNewContactAlertWindowController
46 //Prompt for a new alert.  Pass nil for a panel prompt.
47 + (void)editAlert:(NSDictionary *)inAlert forListObject:(AIListObject *)inObject onWindow:(NSWindow *)parentWindow notifyingTarget:(id)inTarget delegate:(id)inDelegate oldAlert:(id)inOldAlert configureForGlobal:(BOOL)inConfigureForGlobal defaultEventID:(NSString *)inDefaultEventID
49         CSNewContactAlertWindowController       *newAlertwindow = [[self alloc] initWithWindowNibName:(/*showEventsInEditSheet ? 
50                                                                                                                                                                                            NEW_ALERT_NIB :*/
51                                                                                                                                                                                            NEW_ALERT_NO_EVENTS_NIB)
52                                                                                                                                                                                 alert:inAlert
53                                                                                                                                                                 forListObject:inObject
54                                                                                                                                                           notifyingTarget:inTarget
55                                                                                                                                                                          delegate:inDelegate
56                                                                                                                                                                          oldAlert:inOldAlert
57                                                                                                                                                    configureForGlobal:inConfigureForGlobal
58                                                                                                                                                            defaultEventID:inDefaultEventID];
59         
60         if(parentWindow){
61                 [NSApp beginSheet:[newAlertwindow window]
62                    modalForWindow:parentWindow
63                         modalDelegate:newAlertwindow
64                    didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:)
65                           contextInfo:nil];
66         }else{
67                 [newAlertwindow showWindow:nil];
68         }
70         
71 //Init
72 - (id)initWithWindowNibName:(NSString *)windowNibName 
73                                           alert:(NSDictionary *)inAlert
74                           forListObject:(AIListObject *)inListObject
75                         notifyingTarget:(id)inTarget
76                                    delegate:(id)inDelegate 
77                                    oldAlert:(id)inOldAlert
78                  configureForGlobal:(BOOL)inConfigureForGlobal
79                          defaultEventID:(NSString *)inDefaultEventID
81         [super initWithWindowNibName:windowNibName];
82         
83         //
84         oldAlert = [inOldAlert retain];
85         listObject = [inListObject retain];
86         target = inTarget;
87         delegate = inDelegate;
88         detailsPane = nil;
89         configureForGlobal = inConfigureForGlobal;
90         
91         //Create a mutable copy of the alert dictionary we're passed.  If we're passed nil, create the default alert.
92         alert = [inAlert mutableCopy];
93         if(!alert){     
94                 /*
95                 if(!defaultEventID){
96                         defaultEventID = [[adium contactAlertsController] defaultEventID];
97                 }
99                 alert = [[NSMutableDictionary alloc] initWithObjectsAndKeys:inDefaultEventID, KEY_EVENT_ID,
100                                                                                                                                         [[adium contactAlertsController] defaultActionID], KEY_ACTION_ID, nil];
101         }
103         [[adium notificationCenter] addObserver:self
104                                                                    selector:@selector(alertDetailsForHeaderChanged:)
105                                                                            name:CONTACT_ALERTS_DETAILS_FOR_HEADER_CHANGED
106                                                                          object:nil];
108         return(self);
111 //Dealloc
112 - (void)dealloc
114         [[adium notificationCenter] removeObserver:self];
116         [alert release];
117         [oldAlert release];
118         [detailsPane release];
119         [listObject release];
120         
121         [super dealloc];
124 //Setup the window before it is displayed
125 - (void)windowDidLoad
127         if ([[self superclass] instancesRespondToSelector:@selector(windowDidLoad)]){
128                    [super windowDidLoad];
129         }
131         //Configure window
132         [[self window] center];
133         [popUp_event setMenu:[[adium contactAlertsController] menuOfEventsWithTarget:self forGlobalMenu:configureForGlobal]];
134         [popUp_action setMenu:[[adium contactAlertsController] menuOfActionsWithTarget:self]];
136         [[self window] setTitle:AILocalizedStringFromTable(@"New Alert", @"AdiumFramework", nil)];
137         
138         [checkbox_oneTime setLocalizedString:AILocalizedStringFromTable(@"Delete after event occurs", @"AdiumFramework", "New contact alert pane")];
139         [button_OK setLocalizedString:AILocalizedStringFromTable(@"OK", @"AdiumFramework", nil)];
140         [button_cancel setLocalizedString:AILocalizedStringFromTable(@"Cancel", @"AdiumFramework", nil)];
141         
142         [label_Event setLocalizedString:AILocalizedStringFromTable(@"Event:", @"AdiumFramework", "Label for contact alert event (e.g. Contact signed on, Message received, etc.)")];
143         [label_Action setLocalizedString:AILocalizedStringFromTable(@"Action:", @"AdiumFramework", "Label for contact alert action (e.g. Send message, Play sound, etc.)")];    
145         //Remove the single-fire option for global
146         if(configureForGlobal){
147                 if([checkbox_oneTime respondsToSelector:@selector(setHidden:)]){
148                         [checkbox_oneTime setHidden:YES];
149                 }else{
150                         [checkbox_oneTime setFrame:NSZeroRect];
151                 }
152         }
153         
154         //Set things up for the current event
155         [self configureForEvent];
158 //Window is closing
159 - (void)windowWillClose:(id)sender
161         [super windowWillClose:sender];
162         [self cleanUpDetailsPane];
165 //Called as the user list edit sheet closes, dismisses the sheet
166 - (void)sheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo
168     [sheet orderOut:nil];
172 //Buttons --------------------------------------------------------------------------------------------------------------
173 #pragma mark Buttons
174 //Cancel changes
175 - (IBAction)cancel:(id)sender
177         [self closeWindow:nil];
180 //Save changes
181 - (IBAction)save:(id)sender
183         //Save changes in our detail pane
184         [self saveDetailsPaneChanges];
186         //Pass the modified alert to our target
187         [target performSelector:@selector(alertUpdated:oldAlert:) withObject:alert withObject:oldAlert];
188         [self closeWindow:nil];
192 //Controls -------------------------------------------------------------------------------------------------------------
193 #pragma mark Controls
194 //Configure window for our current event dict
195 - (void)configureForEvent
197         NSEnumerator    *enumerator;
198         NSMenuItem              *menuItem;
200         //Select the correct event
201         NSString        *eventID = [alert objectForKey:KEY_EVENT_ID];
202         enumerator = [[popUp_event itemArray] objectEnumerator];
203         while((menuItem = [enumerator nextObject])){
204                 if([eventID isEqualToString:[menuItem representedObject]]){
205                         [popUp_event selectItem:menuItem];
206                         break;
207                 }
208         }
209         
210         //Select the correct action
211         NSString        *actionID = [alert objectForKey:KEY_ACTION_ID];
212         enumerator = [[popUp_action itemArray] objectEnumerator];
213         while((menuItem = [enumerator nextObject])){
214                 if([actionID isEqualToString:[menuItem representedObject]]){
215                         [popUp_action selectItem:menuItem];
216                         break;
217                 }
218         }
219         
220         //Setup our single-fire option
221         if(!configureForGlobal){
222                 [checkbox_oneTime setState:[[alert objectForKey:KEY_ONE_TIME_ALERT] intValue]];
223         }
224         
225         //Configure the action details pane
226         [self configureDetailsPane];
229 //Save changes made in the details pane
230 - (void)saveDetailsPaneChanges
232         //Save details
233         NSDictionary    *actionDetails = [detailsPane actionDetails];
234         if(actionDetails){
235                 [alert setObject:actionDetails forKey:KEY_ACTION_DETAILS];
236         }
238         //Save our single-fire option
239         [alert setObject:[NSNumber numberWithBool:([checkbox_oneTime state] == NSOnState)] forKey:KEY_ONE_TIME_ALERT];
242 //Remove details view/pane
243 - (void)cleanUpDetailsPane
245         [detailsView removeFromSuperview];
246         detailsView = nil;
247         [detailsPane closeView];
248         [detailsPane release];
249         detailsPane = nil;
252 //Configure the details pane for our current alert
253 - (void)configureDetailsPane
255         NSString                                *actionID = [alert objectForKey:KEY_ACTION_ID];
256         id <AIActionHandler>    actionHandler = [[[adium contactAlertsController] actionHandlers] objectForKey:actionID];               
258         //Save changes and close down the old pane
259         if(detailsPane) [self saveDetailsPaneChanges];
260         [self cleanUpDetailsPane];
261         
262         //Get a new pane for the current action type, and configure it for our alert
263         detailsPane = [[actionHandler detailsPaneForActionID:actionID] retain];
264         if(detailsPane){
265                 NSDictionary    *actionDetails = [alert objectForKey:KEY_ACTION_DETAILS];
266                 
267                 detailsView = [detailsPane view];
269                 [detailsPane configureForActionDetails:actionDetails listObject:listObject];            
270                 [detailsPane configureForEventID:[alert objectForKey:KEY_EVENT_ID]
271                                                           listObject:listObject];
272         }
274         //Resize our window for best fit
275         int             currentDetailHeight = [view_auxiliary frame].size.height;
276         int             desiredDetailHeight = [detailsView frame].size.height;
277         int             difference = (currentDetailHeight - desiredDetailHeight);
278         NSRect  frame = [[self window] frame];
279         [[self window] setFrame:NSMakeRect(frame.origin.x, frame.origin.y + difference, frame.size.width, frame.size.height - difference)
280                                         display:[[self window] isVisible]
281                                         animate:[[self window] isVisible]];
282         
283         //Add the details view
284         if(detailsView) [view_auxiliary addSubview:detailsView];
285                 
286         //Pull any default values the pane set in configureForActionDetails
287         [self saveDetailsPaneChanges];
288         
289         //And use them to update our header view
290         [self updateHeaderView];
293 //User selected an event from the popup
294 - (IBAction)selectEvent:(id)sender
296         NSString        *eventID;
297         if((eventID = [sender representedObject])){
298                 [alert setObject:eventID forKey:KEY_EVENT_ID];
299                 
300                 [detailsPane configureForEventID:eventID
301                                                           listObject:listObject];
302                                 
303                 [self updateHeaderView];
304         }
306         
307 //User selected an action from the popup
308 - (IBAction)selectAction:(id)sender
310         if([sender representedObject]){
311                 NSString        *newAction = [sender representedObject];
312                 NSString        *oldAction = [alert objectForKey:KEY_ACTION_ID];
313                 
314                 if(![newAction isEqualToString:oldAction]){
315                         [alert setObject:[sender representedObject] forKey:KEY_ACTION_ID];
316                         
317                         [self configureDetailsPane];
318                 }
319         }
322 - (void)alertDetailsForHeaderChanged:(NSNotification *)aNotification
324         [self saveDetailsPaneChanges];
325         [self updateHeaderView];
328 - (void)updateHeaderView
330         NSString                                *actionID = [alert objectForKey:KEY_ACTION_ID];
331         NSString                                *eventID = [alert objectForKey:KEY_EVENT_ID];
332         NSString                                *eventDescription = [[adium contactAlertsController] longDescriptionForEventID:eventID 
333                                                                                                                                                                                          forListObject:listObject];
334         id <AIActionHandler>    actionHandler = [[[adium contactAlertsController] actionHandlers] objectForKey:actionID];
336         if(actionHandler && eventDescription){
337                 [headerView setStringValue:eventDescription];
338                 [headerView setImage:[actionHandler imageForActionID:actionID]];
339                 [headerView setSubString:[actionHandler longDescriptionForActionID:actionID
340                                                                                                                  withDetails:[alert objectForKey:KEY_ACTION_DETAILS]]];
341                 [headerView setNeedsDisplay:YES];
342         }
345 @end